<template>
	<div class="root">
		<an-nav></an-nav>

		<!-- 头部搜索区域 -->
		<div class="c2 flex">
			<div class="c3">
				<el-input :placeholder="$l('请输入需要搜索的关键词','form.t1')" v-model="searchData.keyWord" clearable
					@clear="getList">
					<template #prepend>
						<el-select v-model="searchData.type" @change="searchFun" :placeholder="$l('请选择','form.t2')"
							class="c6">
							<el-option label="全部类型" value="">
							</el-option>
							<el-option v-for="(v,i) in pageData.typeList" :key="i" :label="v.name"
								:value="v.type_id || id">
							</el-option>
						</el-select>
					</template>
					<template #append>
						<el-button :icon="Search" @click="searchFun" />
					</template>
				</el-input>
			</div>
			<div class="c4">
				<el-button v-if="pData.option.showExport" @click="emit('exportExecl',pageData.list)">
					导出execl
				</el-button>
				<el-popconfirm confirm-button-text="确定" cancel-button-text="取消" icon-color="red" title="确定删除选中数据？"
					@confirm="delData()">
					<template #reference>
						<el-button type="warning" :disabled="!pageData.checkedArr.length">批量删除</el-button>
					</template>
				</el-popconfirm>

				<el-button type="primary" v-if="pData.option.showAddBut" @click="showAddFun()">
					新增{{pData.option.name}}
				</el-button>
				<!-- <el-button type="danger"  :disabled="!pageData.checkedArr.length" @click="switchStateData(0)">批量下架</el-button>
                <el-button type="primary"  :disabled="!pageData.checkedArr.length" @click="switchStateData(1)">批量上架</el-button> -->
			</div>
		</div>

		<!-- 数据列表 -->
		<el-table 
			:default-sort="{ prop: 'id', order: 'descending' }"
			@sort-change="sortChange"	
			v-loading="loading" 
			:data="pageData.list" 
			ref="tableRef" 
			stripe 
			style="width: 100%" 
			:height="clientWidth < 960?'calc(100vh - 260px)':'calc(100vh - 234px)'"
			@selection-change="selectChecked">
			<!-- 展开行 -->
			<el-table-column type="expand">
				<template #default="props">

					<!-- 插槽 -->
					<slot name="open" :data="props.row" :typelist="pageData.typeList">
						<pre>
						{{props.row}}
						</pre>
					</slot>

					<!-- <div><span>标题: </span>{{ props.row.productName }}</div> -->
				</template>
			</el-table-column>

			<!-- 单选框 -->
			<el-table-column type="selection" width="38" />
			<el-table-column prop="id" sortable="custom" label="编号" width="80"> </el-table-column>

			<!-- 插槽 -->
			<slot :typelist="pageData.typeList"></slot>

			<el-table-column align="center" width="100" label="状态" :filters="[
					{ text: '显示', value: '1' },
					{ text: '隐藏', value: '0' },
				]" :filter-method="filterTag" filter-placement="bottom-end">
				<template #default="scope">
					<el-tag v-if="scope.row.a_show == '1'" type="success">显示</el-tag>
					<el-tag v-else type="info">隐藏</el-tag>
				</template>
			</el-table-column>

			<el-table-column prop="create_time" label="创建时间" width="180">
				<template #default="scope">
					{{time(scope.row.create_time,"yyyy-mm-dd hh:MM:ss")}}
				</template>
			</el-table-column>

			<!-- 右边操作按钮 -->
			<el-table-column label="操作" :width="pData.option.activeWidth" fixed="right" align="center">
				<template #default="scope">
					<div class="flex">

						<!-- 页面上其他按钮 -->
						<slot name="but" :data="scope.row"></slot>

						<!-- 编辑按钮 -->
						<div v-if="pData.option.showEditBut">
							<el-button type="text" size="small" @click="showAddFun(scope.row)">
								编辑
							</el-button>
						</div>
						
						<!-- 删除按钮 -->
						<div v-if="pData.option.delUrl">
							<el-popconfirm confirm-button-text="确定" cancel-button-text="取消" icon-color="red"
								title="确定删除当前数据？" @confirm="delData(scope.row.id,'one')">
								<template #reference>
									<el-button type="text" size="small">删除</el-button>
								</template>
							</el-popconfirm>
						</div>
					</div>
				</template>
			</el-table-column>
		</el-table>

		<!-- 分页 -->
		<div class="c5">
			<el-pagination :small="clientWidth < 960"  background :default-page-size="searchData.limit" @size-change="switchSizeChange"
				@current-change="switchCurrentChange" v-model:currentPage="searchData.page" :pager-count="5"
				:layout="clientWidth < 960?'total,prev, pager, next':'total,prev, pager, next,sizes'" :page-sizes="[10, 20, 30, 40, 50, 100]" :total="pageData.total">
			</el-pagination>
		</div>

		<el-dialog v-model="editForm.show" :append-to-body="false" top="10vh"
			:title="(editForm.form?.id?'编辑':'新增')+pData.option.name">

			<el-scrollbar max-height="65vh" ref="scrollRef">
				<div style="width: calc(100% - 50px);margin: 0 auto;">
					<el-form label-width="80px" label-position="top" ref="ruleFormRef" :model="editForm.form" :rules="rules">

						<el-form-item label="分类：" v-if="pData.option.showType" prop="type">
							<el-select :teleported="false" v-model="editForm.form.type" placeholder="选择分类">
								<el-option v-for="(v,i) in pageData.typeList" :key="v.id" :label="v.name"
									:value="v.type_id">
								</el-option>
							</el-select>
						</el-form-item>

						<slot name="form" :form="editForm.form" :typelist="pageData.typeList"></slot>

						<el-form-item label="图片：" v-if="pData.option.showCover">
							<div class="c16" @click="selectImg('img')">
								<el-image 
									v-if="editForm.form.image" 
									style="width: 100%; height: 100%" 
									:src="pickImg.serverImg + editForm.form.image"  
									fit="scale-down" />
							
								<i class="iconfont custom-icon-delete2-copy" v-else></i>
							</div>
						</el-form-item>

						<el-form-item label="详情：" v-if="pData.option.showEdit">
							<div>
								<editor ref="editorRef" @selectImg="selectImg"></editor>
							</div>
						</el-form-item>

					</el-form>
				</div>
			</el-scrollbar>

			<template #footer>
				<div class="flex c8">
					<div>
						<template v-if="pData.option.showDisable">
							是否显示：
							<el-switch active-value="1" inactive-value="0" v-model="editForm.form.a_show"
								active-text="显示" inactive-text="隐藏">
							</el-switch>
						</template>
					</div>
					<span class="dialog-footer">
						<el-button @click="editForm.show = false">取消</el-button>
						<el-button type="primary" @click="onSubmit">保存</el-button>
					</span>
				</div>
			</template>
		</el-dialog>
	</div>

	<keep-alive>
		<aImgLocal
			v-if="editForm.show"
			:spaceValue="pickImg.spaceValue"
			v-model:show="pickImg.showLocal"
			:name="pickImg.name" 
			@img="imgSuccess">
		</aImgLocal>
	</keep-alive>

</template>

<script setup>
	import time from "@/utils/timeFormat.js";
	import { Search } from '@element-plus/icons-vue'
	
	import editor from "@/components/editor/index.vue";
	const editorRef = ref(null);
	
	import publicJS from "@/hook/public.js";
	const {
		ElMessage,
		config,
		api
	} = publicJS();
	
	const emit = defineEmits(["exportExecl","getData","editHandle","subForm"]); //自定义事件
	
	//接受父组件参数
	const props = defineProps({
		option: {
			type: Object,
			default: () => {
				return {}
			}
		},
		//表单校验规则
		rules:{
			type: Object,
			default: () => {
				return {}
			}
		}
	})
	
	const pData = reactive({
		//页面配置项
		option:{
			name: '', //页面个性名称
			activeWidth:'110',//最左边操作栏宽度
			spaceValue: 'local', //图片空间 local本地图片 其他为七牛云
			showAddBut: false, //是否需要显示添加按钮
			showEditBut: false, //是否需要编辑按钮
			showExport: false, //是否需要导出execl
			showEdit: false, //是否需要编辑器
			showCover: false, //是否需要封面图
			showType: false, //是否需要类型
			showDisable: false, //是否需要禁用/隐藏/下架按钮
			getUrl: '', //获取列表url
			delUrl: '', //删除数据url
			getEditUrl: '', //获取需要编辑的数据url
		}
	})
	
	pData.option = {...pData.option,...props.option}

	const clientWidth = ref(document.body.clientWidth);
	import useWindowSize from "@/hook/useWindowSize.js";
	useWindowSize(function(w,h){
		clientWidth.value = w;
	});
	
	//图片选择组件
	import useSelectImg from "@/hook/useSelectImg.js";
	const {aImgLocal,pickImg,selectImg,imgSuccess} = useSelectImg(pData.option.spaceValue,res=>{
		if(res.name == 'img'){
			editForm.form.image = res.value;
		}
		if(res.name == 'editor'){
			editorRef.value.editorObj.execCommand(
				'inserthtml', 
				`<p><img style='max-width:100%' src='${pickImg.serverImg}${res.value}'/></p>`
			);
		}
	});


	//筛选当前页数据的 状态
	const filterTag = (value, row) => {
		return row.a_show === value
	}

	const scrollRef = ref(null);

	const editForm = reactive({
		show: false,
		form: {}
	})

	//打开弹窗编辑
	const showAddFun = (data) => {
		editForm.show = true;

		nextTick(() => {
			scrollRef.value.setScrollTop(0)
		})
		if (data) {
			//编辑 
			editForm.form.id = data.id;
			if (pData.option.getEditUrl) {
				api.post(pData.option.getEditUrl, {
					id: data.id
				}).then(r => {
					if (r.data.details != null) {
						editForm.form = r.data.details;

						if (pData.option.showEdit) {
							nextTick(() => {
								editorRef.value.content = r.data.details?.content || '';
							})
						}

						//个性化操作，让父组件处理
						emit('editHandle', r.data.details)
					}
				})
			} else {
				editForm.form = data;
				emit('editHandle', data) //个性化操作，让父组件处理
			}
		} else {
			//新增
			editForm.form = {
				a_show: '1'
			};
			if (pData.option.showEdit) {
				nextTick(() => {
					//给编辑器赋值初始内容 如：<h2>Hello World!</h2>
					editorRef.value.content = ""
				})
			}
			emit('editHandle', null) //个性化操作，让父组件处理
		}
	}

	//弹窗编辑数据提交
	const onSubmit = () => {
		if (pData.option.showEdit) editForm.form.content = editorRef.value.content;
		emit('subForm', editForm.form)
	}

	// 获取列表 条件
	const searchData = reactive({
		keyWord: '',
		type: '',
		page: 1,
		limit: 20,
		prop:'id',//需要排序的字段
		sort:'desc',//desc asc
	})
	
	// 获取列表
	const pageData = reactive({
		all:null,
		total: 0,
		list: [],
		typeList: [],
		checkedArr: []
	})
	
	// const {...toRef(pageData)}

	//改变排序规则
	const sortChange = (e)=>{
		if(e.prop){
			searchData.prop = e.prop
			searchData.sort = e.order == 'ascending'?'asc':'desc'
		}else{
			searchData.prop = ''
		}
		getList();
	}
	
	//获取列表数据
	const loading = ref(false)
	const getList = () => {
		loading.value = true
		api.post(pData.option.getUrl, searchData).then(res => {
			pageData.all = res;
			pageData.total = res.total;
			pageData.typeList = res.data.type;
			pageData.list = res.data.list;
			loading.value = false;
			emit('getData', res) //返回页面所有数据，让父组件进行个性操作
		})
	}
	getList();

	//搜索
	const searchFun = () => {
		editForm.show = false; //关闭编辑弹窗
		searchData.page = 1;
		getList();
	}

	// 切换每页条数
	const switchSizeChange = (val) => {
		console.log(`每页 ${val} 条`)
		searchData.limit = val;
		getList();
	}

	// 点击分页
	const tableRef = ref(null);
	const switchCurrentChange = (val) => {
		console.log(`当前页: ${val}`)
		tableRef.value.setScrollTop(0)
		getList();
	}

	//删除数据
	const delData = (v, type) => {
		//判断是否删除多条
		let ids = type == 'one' ? [v] : pageData.checkedArr;
		console.log(ids);
		api.post(pData.option.delUrl, {
			ids
		}).then(res => {
			getList();
			ElMessage.success('操作成功');
		})
	}

	//上下架数据
	const switchStateData = (state) => {
		api.post('a/goods/switch_state_data_a', {
			ids: pageData.checkedArr,
			state
		}).then(res => {
			getList();
			ElMessage.success('操作成功');
		})
	}

	//获取选中的数据id
	const selectChecked = (val) => {
		pageData.checkedArr = val.map(v => {
			return v.id
		})
	}

	const ruleFormRef = ref(null);//获取表单ref,用来校验表单

	//暴露方法给父组件 通过ref.value调用
	defineExpose({
		ruleFormRef,
		searchFun,
		editorRef,
		editForm,
		pageData
	})
</script>

<style lang="scss" scoped>
	.root {
		background: #fff;
		padding: 0 10px 10px;

		&:deep(.el-dialog__body) {
			padding: 10px 0 5px;
		}

		&:deep(.el-dialog) {
			width: 80%;
			max-width: 1200px;
		}
	}

	.c2 {
		padding: 0 0 10px;
		justify-content: space-between;
	}

	.c3 {
		max-width: 600px;
	}

	.c5 {
		margin-top:10px;
	}

	.c6 {
		width: 130px;
	}

	.c7 {
		line-height: 26px;
	}

	.c7 span {
		display: inline-block;
		width: 80px;
	}

	.c8 {
		justify-content: space-between;
	}

	.c16 {
		border: 1px dashed #d9d9d9;
		height: 169px;
		width: 300px;
		cursor: pointer;
		text-align: center;
		line-height: 169px;
	}

	.c16 .iconfont {
		font-size: 36px;
		color: #888;
	}

	.c16:hover {
		border-color: var(--el-color-primary);
	}

	.c16 img {
		width: 100%;
		height: 100%;
	}

	@media screen and (max-width: 960px) {
		.c2{display: block;}
		.c3{margin-bottom: 8px;}
		.c6 {
			width: 100px;
		}
	}
</style>
